fn main() {
    let out_dir = std::env::var("OUT_DIR").unwrap();

    let bindings_path = std::path::PathBuf::from(&out_dir).join("bindings.rs");
    bindgen::Builder::default()
        .ctypes_prefix("::libc")
        .allowlist_file(".*/puffin/[^/]+\\.h")
        .allowlist_recursively(false)
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .rustified_enum(".*")
        .derive_copy(true)
        .derive_debug(true)
        .derive_eq(true)
        .derive_default(true)
        .derive_partialeq(true)
        .impl_partialeq(true)
        .impl_debug(true)
        .header("include/puffin/puffin.h")
        .generate()
        .expect("Unable to generate Rust bindings for C harness")
        .write_to_file(&bindings_path)
        .expect("Couldn't write bindings for C harness!");

    println!(
        "cargo:rustc-env=C_BINDINGS_FILE={}",
        bindings_path.to_string_lossy()
    );

    let src_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let inc_dir = src_dir.join("include");
    let dst_dir = std::path::PathBuf::from(out_dir);

    std::fs::create_dir_all(&inc_dir).unwrap();

    // NOTE cc automatically emits link flags for cargo
    //
    //     Alongside the rust bindings file generated by bindgen, this build
    //     script creates the `puffin-harness-c` library containing the
    //     C-implemented part of the `puffin` library. This is
    //     specified through the `links` field in Cargo.toml.
    //
    //     It might be confusing that we never actually tell cargo where to find
    //     this native library. This is because the `cc` crate automatically
    //     emits these flags.
    //
    //     If we ever replace `cc`, we will need to manually emit the cargo
    //     metadata `cargo:rustc-link-lib` and `cargo:rustc-link-search`.
    cc::Build::new()
        .include(&inc_dir)
        .file("src/harness.c")
        .compile("puffin-harness-c");

    println!("cargo:root={}", dst_dir.to_str().unwrap());
    println!("cargo:include={}", inc_dir.to_str().unwrap());
}
